<template>
  <span class="ui-select" :class="{'is-disabled': disabled, 'is-loading': refreshing}">
    <template v-if="editable">
      <el-select
        class="ui-select__control"
        v-model="innerValue"
        size="small"
        :disabled="disabled"
        :multiple="multiple"
        :placeholder="placeholder"
        :clearable="clearable"
        :style="{width: '100%'}"
        @change="handleChange"
      >
        <slot></slot>
        <el-option
          class="ui-select__item"
          v-for="item in options"
          :key="item[valueField]"
          :value="item[valueField]"
          :label="item[textField]"
        >
          <slot name="item" :item="item">
            {{item[textField]}}
          </slot>
        </el-option>
      </el-select>
    </template>
    <template v-else>
      {{ showText }}
    </template>
    <span class="ui-select__loading" v-if="refreshing">
      <ui-icon name="loading"></ui-icon> 数据加载中...
    </span>
  </span>
</template>
<script>
import Select from 'element-ui/lib/select'
import Option from 'element-ui/lib/option'
import 'element-ui/lib/theme-chalk/select.css'
import 'element-ui/lib/theme-chalk/option.css'
import { isEmpty } from '@/utils/util'

export default {
  name: 'UiSelect',
  components: {
    ElSelect: Select,
    ElOption: Option
  },
  props: {
    items: {
      type: Array,
      default: () => []
    },
    clearable: {
      type: Boolean,
      default: true
    },
    placeholder: {
      type: String,
      default: '选择'
    },
    value: {
      type: [Number, String, Array, Boolean]
    },
    multiple: {
      type: Boolean
    },
    textField: {
      type: String,
      default: 'label'
    },
    valueField: {
      type: String,
      default: 'id'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    queryMethod: {
      type: Function
    },
    lazy: {
      type: Boolean,
      default: false
    },
    editable: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      pageIndex: 1,
      pageSize: 20,
      loading: false,
      refreshing: false,
      moring: false,
      notMore: false,
      options: this.items
    }
  },
  computed: {
    innerValue: {
      get () {
        let value = this.value
        if (this.value && Array.isArray(this.value)) {
          if (!this.multiple) {
            value = this.value[0]
          }
        }
        return value
      },
      set (val) {
        this.$emit('input', val)
      }
    },
    showText () {
      if (this.multiple) {
        if (!Array.isArray(this.innerValue)) {
          return ''
        }
        return this.options.filter(v => this.innerValue.includes(v[this.valueField])).map(v => v[this.textField]).join('、')
      } else {
        if (isEmpty(this.innerValue)) {
          return ''
        }
        return this.options.filter(v => v[this.valueField] === this.innerValue).map(v => v[this.textField])[0] || ''
      }
    },
    loadMoreStatus () {
      let status = 'loadmore'
      if (this.notMore) {
        status = 'nomore'
      } else if (this.moring) {
        status = 'loading'
      }
      return status
    }
  },
  watch: {
    items () {
      this.options = this.items
    }
  },
  created () {
    // 尝试加载远程被选项
    // 如果没有value的情况，可以显示下拉时在加载
    this.reload()
  },
  methods: {
    reload () {
      const rs = this.loadOptions()
      if (rs && rs.then) {
        this.refreshing = true
        rs.then((rs) => {
          this.options = rs || []
        }).finally(() => {
          this.refreshing = false
        })
      }
    },
    loadMoreOptions () {
      const nextPageIndex = this.pageIndex + 1
      const rs = this.loadOptions(nextPageIndex)
      if (rs && rs.then) {
        this.moring = true
        rs.then((rs) => {
          this.options = [].concat(this.options, rs || [])
        }).finally(() => {
          this.moring = false
        })
      }
    },
    /**
     * 加载远程备选项
    */
    loadOptions (pageIndex) {
      if (!this.queryMethod) {
        return
      }
      this.loading = true
      const params = {}
      if (this.lazy) {
        params.page_num = pageIndex || this.pageIndex
        params.page_size = this.pageSize
      }
      return this.queryMethod(params).then((rs) => {
        this.notMore = rs.length < this.pageSize
        return rs
      }).finally(() => {
        this.loading = false
      })
    },
    handleChange (value) {
      if (value) {
        const item = this.options.find(v => v[this.valueField] === value)
        this.$emit('change', {
          value,
          item
        })
      } else {
        this.$emit('change', {
          value,
          item: null
        })
      }
    },
    handleLoadMoreClick () {
      this.loadMoreOptions()
    }
  }
}
</script>
<style lang="less">
.ui-select{
  display: inline-block;
  position: relative;
  width: 100%;
  &.is-disabled{
    .ui-select__loading{
      background-color: #f6f7fa;
    }
  }
  .el-select{
    vertical-align: top;
  }
  .el-input__inner{
    font-size: 14px;
  }
  &.is-loading{
    .el-select__tags{
      display: none;
    }
  }
}
.ui-select__loading{
  position: absolute;
  top: 2px;
  left: 2px;
  right: 2px;
  bottom: 2px;
  padding-left: 10px;
  z-index: 3;
  height: 28px;
  line-height: 28px;
  color: #999;
  background-color: #fff;
  border-radius: 3px;
}
.ui-select{
  // .el-input{
  //   &.is-focus{
  //     .el-input__inner{
  //       border-color: #4389fa;
  //       box-shadow: 0 0 0 0.2rem rgba(26, 162, 232,.25);
  //     }
  //   }
  // }
  .el-input__inner{
    transition: all .15s ease-in-out;
    padding-left: 11px;
    padding-right: 11px;
    color: #404040;
    // &:focus{
    //   border-color: #4389fa;
    //   box-shadow: 0 0 0 0.2rem rgba(26, 162, 232,.25);
    // }
  }
}
.ui-select__item.el-select-dropdown__item.selected{
  color: #28a4e6;
}
</style>
